package org.zkoss.zktc.core.groovy;

import groovy.lang.Binding;

import java.util.List;

import org.zkoss.zktc.core.groovy.Snippet.Status;

public class SnippetRunner {

	String imports;
	List<Snippet> snippets;
	int index = 0;
	
	Engine engine;
	
	public int getIndex(){
		return index;
	}
	
	public Snippet getSnippet(){
		return index<snippets.size()?snippets.get(index):null;
	}

	public SnippetRunner(List<Snippet> snippets, Binding binding) {
		this.snippets = snippets;
		engine = new Engine(binding);
		StringBuilder sb = new StringBuilder();
		for(Snippet s:snippets){
			String code = s.getCode().trim();
			if(code.startsWith("import ")){
				sb.append(code).append(code.endsWith(";")?"":";");
			}
		}
		imports = sb.toString();
		
	}

	public SnippetRunner(List<Snippet> snippet) {
		this(snippet, new Binding());
	}

	public void run()throws ExecutionException{
		while (stepOver()) {
		}
	}

	public boolean hasNextStep(){
		return index < snippets.size();
	}
	
	public boolean stepOver()throws ExecutionException{
		return stepOver(index);
	}

	public boolean stepOver(int index)throws ExecutionException {
		if (index >= snippets.size()) {
			return false;
		}
		Snippet s = snippets.get(index);
		execute(s);
		this.index = index+1;
		return true;
	}

	private void execute(Snippet s)throws ExecutionException {
		String c = s.getCode().trim();
		if("".equals(c)) {
			s.setStatus(Status.FINE);
			s.clearErr();
			return;
		}
		
		StringBuilder code = new StringBuilder();
		code.append(imports);
		//for correct snippet index when error
		for(int i=0;i<index;i++){
			code.append("\n");
		}
		code.append(c);
		try{
			engine.execute(code.toString());
		}catch(ExecutionException ex){
			s.setStatus(Status.ERROR);
			s.setErr(ex);
			throw ex;
		}
		s.setStatus(Status.FINE);
		s.clearErr();
	}

	public void stop() {
		index = 0;
	}

	public Engine getEngine() {
		return engine;
	}
	
	public Binding getBinding(){
		return engine.getBinding();
	}

}
